package com.chuangke.common.advice;

import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.sql.DataTruncation;
import java.sql.SQLIntegrityConstraintViolationException;
import java.util.stream.Collectors;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;

import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import com.chuangke.common.exception.ChuangkeException;
import com.chuangke.common.http.HttpResult;
import com.chuangke.common.http.HttpStatus;
import com.chuangke.common.utils.ExceptionUtil;
import com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException;

import cn.hutool.core.exceptions.ValidateException;

@ControllerAdvice
@ResponseBody
public class ExceptionAdvice {

	private static final Logger logger = LoggerFactory.getLogger(ExceptionAdvice.class);

	@ExceptionHandler(value = Throwable.class)
	public HttpResult exceptionHandler(Throwable exception) {
		Throwable ex = ExceptionUtil.getSourceException(exception);
		logger.error("exception", exception);
		String message = "";
		if (ex instanceof ConstraintViolationException) {
			message = getMessage((ConstraintViolationException) ex);
		} else if (ex instanceof ChuangkeException) {
			message = ex.getMessage();
		} else if (ex instanceof ValidateException) {
			message = ex.getMessage();
		} else if (ex instanceof AccessDeniedException) {
			return HttpResult.error(HttpStatus.SC_UNAUTHORIZED, ex.getMessage());
		} else if (ex instanceof SQLIntegrityConstraintViolationException) {
			message = String.format("数据库异常：[%s]", ex.getMessage());
		} else if (ex instanceof MySQLTransactionRollbackException) {
			message = "处理超时，请重新处理！";
		} else if (ex instanceof DuplicateKeyException) {
			message = "操作失败，存在重复数据！";
		} else if (ex instanceof DataTruncation) {
			message = "操作失败，字数太长！";
		} else if (ex instanceof SocketException) {
			message = "网络连接异常：" + ExceptionUtils.getMessage(ex);
		} else if (ex instanceof SocketTimeoutException) {
			message = "网络连接超时：" + ExceptionUtils.getMessage(ex);
		} else if (ex instanceof BadCredentialsException) {
			message = ex.getMessage();
		} else {
			message = "服务端异常：" + ExceptionUtils.getMessage(ex);
		}
//		String detailMsg = ExceptionUtils.getStackTrace(ex);
		String detailMsg = null ;
		return HttpResult.error(message, detailMsg);
	}

	public String getMessage(ConstraintViolationException e) {
		return e.getConstraintViolations().stream().map(ConstraintViolation::getMessage)
				.collect(Collectors.joining(","));
	}

}
